package com.jiazhong.aop.xml;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @Auther:shuXin
 */
//确保这个类是一个切面类
@Aspect
//确保这个类被Spring来进行管理
@Component
public class LogAspect {
    // 设置切入点和通知类型
    // 切入点表达式execution(访问修饰符 增强方法返回类型 增强方法所在类全路径.方法名(参数列表))
    // 通知类型：
    // 前置 @Before(value="切入点表达式配置切入点")
    // 返回 @AfterReturning
    // 异常 @AfterThrowing
    // 后置 @After
    // 环绕 @Around
    //@Before("execution(public int com.jiazhong.aop.annoaop.CalculatorImpl.*(..))")
    public void beforeMethod(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        String args = Arrays.toString(joinPoint.getArgs());
        System.out.println("Logger-->前置通知，方法名："+methodName+"，参数："+args);
    }
    //@AfterReturning(argNames = "pointCat()",returning = "result")
    public void afterReturn(JoinPoint joinPoint,Object result){
        String name = joinPoint.getSignature().getName();
        System.out.println("Logger-->返回通知，方法名："+name+"，结果："+result);
    }
    //@AfterThrowing(value = "execution(* com.jiazhong.aop.annoaop.CalculatorImpl.*(..)))",throwing = "e")
    public void afterThrow(JoinPoint joinPoint, Throwable e){
        String name = joinPoint.getSignature().getName();
        System.out.println("Logger-->异常通知，方法名："+name+"，异常："+e);
    }
    public void afterMethod(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println("Logger-->后置通知，方法名："+name);
    }
    //环绕通知
    public Object aroundMethod(ProceedingJoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        String[] args = new String[]{Arrays.toString(joinPoint.getArgs())};
        //执行的方法
        Object result = null;
        try {
            System.out.println("Logger-->环绕通知之前，方法名："+name+"，参数："+args);
            result = joinPoint.proceed();
            System.out.println("Logger-->环绕通知之后，方法名："+name+"，结果："+result);
        } catch (Throwable e) {
            //异常处理
            e.printStackTrace();
            System.out.println("Logger-->环绕通知异常，方法名："+name+"，异常："+e);
        } finally {
            //执行完毕
            System.out.println("Logger-->环绕通知结束，方法名："+name);
        }
        return result;
    }

    //重用切入点的表达式
    /*@Pointcut("execution(* com.jiazhong.aop.xml.CalculatorImpl.*(..)))")
    public void pointCat(){

    }*/
}
